﻿///Code based on
/// http://snipd.net/minimax-algorithm-with-alpha-beta-pruning-in-c

using System;
using System.Collections.Generic;
using System.Linq;
using Core.Models;
using Core.Models.Enums;

namespace Service.AI
{
    public class LearningNode
    {
        public GameState gs;
        private ChessPieceColor currentPlayer;
        public MovesInfo currentMi { get; set; }
        public MovesInfo ogMove { get; set; }
        public List<double> bestHeuristic;
        public double? Score = null;
        public bool isAttacking { get; set; }
        public LearningNode(GameState p_Gs)
        {
            isAttacking = false;
            gs = p_Gs;
            currentMi = new MovesInfo();
            currentPlayer = gs.WhoseMove;
        }

        public LearningNode(GameState p_Gs, MovesInfo mi, MovesInfo p_ogMove)
        {
            isAttacking = false;
            gs = p_Gs;
            ogMove = p_ogMove;
            if (mi != null)
            {
                if (gs.MovePiece((byte) mi.SourceColumn, (byte) mi.SourceRow, (byte) mi.DestColumn,(byte) mi.DestRow))
                {
                    currentMi = mi;
                }
                else
                {
                    currentMi = null;
                }
            }
            currentPlayer = gs.WhoseMove;
        }

        public LearningNode(GameState p_Gs, MovesInfo mi, MovesInfo p_ogMove, bool p_IsAttacking)
        {
            isAttacking = p_IsAttacking;
            gs = p_Gs;
            ogMove = p_ogMove;
            if (mi != null)
            {
                if (gs.MovePiece((byte)mi.SourceColumn, (byte)mi.SourceRow, (byte)mi.DestColumn, (byte)mi.DestRow))
                {
                    currentMi = mi;
                }
                else
                {
                    currentMi = null;
                }
            }
            currentPlayer = gs.WhoseMove;
        }

        public List<LearningNode> Children()
        {
            if (currentMi != null )
            {
                List<LearningNode> children = new List<LearningNode>();
                List<MovesInfo> listMoves = gs.GetBoardMoves();
                for (int i = 0; i < listMoves.Count ; i++)
                {
                    bool newIsAtk = false;
                    if (gs.GetPieceTypeAt((byte)listMoves[i].DestColumn, (byte)listMoves[i].DestRow) != ChessPieceType.None)
                    {
                        if (gs.GetPieceColorAt((byte) listMoves[i].DestColumn, (byte) listMoves[i].DestRow) != gs.WhoseMove)
                            newIsAtk = true;
                    }

                    if (ogMove == null)
                    {
                        GameState newGs = new GameState(gs.GetBoardFen(true));
                        newGs.WhoseMove = currentPlayer;
                        children.Add(new LearningNode(newGs, listMoves[i], listMoves[i],newIsAtk));
                    }
                    else
                    {
                        GameState newGs = new GameState(gs.GetBoardFen(true));
                        newGs.WhoseMove = currentPlayer;
                        children.Add(new LearningNode(newGs, listMoves[i], ogMove,newIsAtk));
                    }
                }
                // Create your subtree here and return the results
                var childrenList = children.Where(c => c.currentMi != null).OrderByDescending(c => c.isAttacking).ToList();
                //var childrenList = children.Where(c => c.currentMi != null).ToList();

                return childrenList;
            }

            return null;
        }
    }
}